package cn.jsj.invite.interceptor;


import cn.hutool.core.util.RandomUtil;
import cn.jsj.invite.pojo.UserEnt;
import cn.jsj.invite.pojo.identity.UserIdentityEnum;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author 卢斌
 */
@Component
public class TokenCensor {

    private final RedisTemplate<String, Serializable> redisTemplate;

    @Value("${login-available-time}")
    private Long tokenEffectTime;

    @Autowired
    public TokenCensor(RedisTemplate<String, Serializable> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * Token构造
     *
     * @param userId       用户Id
     * @param identityEnum 用户身份
     * @param sessionKey   一个随意字符串
     * @return token
     */
    private String buildToken(Long userId, UserIdentityEnum identityEnum, String sessionKey) {
        JwtBuilder jwtBuilder = Jwts.builder().setId(userId.toString()).setSubject(identityEnum.toString())
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, sessionKey);
        return jwtBuilder.compact();
    }

    public String tokenIssue(Long userId, UserIdentityEnum identityEnum) {
        String sessionKey = RandomUtil.randomString(16);
        String token = this.buildToken(userId, identityEnum, sessionKey);
        redisTemplate.opsForValue().set(token, sessionKey, tokenEffectTime, TimeUnit.SECONDS);
        return token;
    }


    public UserEnt parseToken(String tokenStr, String sessionKey) {
        Claims claims = Jwts.parser().setSigningKey(sessionKey).parseClaimsJws(tokenStr).getBody();
        UserEnt dto = new UserEnt();
        dto.setId(Long.parseLong(claims.getId()));
        dto.setUserIdentity(UserIdentityEnum.valueOf(claims.getSubject()));
        return dto;
    }

}
